using System;
using System.Collections.Generic;
using System.Text;
using Evolution.Engine.Interfaces;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections;
using System.Data;
using Evolution.Engine.Managers;
using System.Reflection;
using Evolution.Engine.Utilities;

namespace Evolution.Engine.SpatialTrees
{
    public class Scene : ISpatialTree
    {
        internal static int MaxObjectsPerNode = 5;
        internal static bool DrawOctnodes = true;
        internal static Color LineColor = Color.Red;
        internal static VertexDeclaration VertexDeclaration;
        internal Scenenode Root = new Scenenode(Vector3.Zero, 100.0f);

        internal int NodesDrawn = 0;
        internal ArrayList ObjectsDrawn = new ArrayList();

        public BaseObject Find(string name)
        {
            return Root.Find(name);
        }

        public ScenenodeCollection Nodes()
        {
            return Root.Nodes;
        }

        public void LoadContent()
        {
            VertexDeclaration = new VertexDeclaration(GameEngine.Instance.Device, VertexPositionColor.VertexElements);
            Root.LoadContent();
        }

        #region ISpatialTree Members

        public void Update(GameTime gameTime)
        {
            Root.Update(gameTime);
        }

        public void Draw(GameTime gameTime)
        {
            NodesDrawn = 0;
            ObjectsDrawn.Clear();
            Root.Culled = false;
            Root.Draw(gameTime);
        }

        #endregion

        #region ISpatialTree Members

        public void Add(BaseObject baseobject)
        {
            Root.AddObject(baseobject);
        }

        #endregion

        #region ISpatialTree Members


        public void LoadFromFile(string asset)
        {
            DataSet file = new DataSet("SceneFile");
            file.ReadXml(GameUtils.ExecutingDirectory + asset);

            foreach (DataTable table in file.Tables)
            {
                foreach (DataRow row in table.Rows)
                {
                    switch (row["entrytype"].ToString())
                    {
                        case "vegetation":
                            ProcessSceneVegetationType(row);
                            break;

                        case "geometry":
                            ProcessSceneGeometry(row);
                            break;

                        case "environment":
                            ProcessSceneEnvironment(row);
                            break;

                        default:
                            break;
                    }
                }
            }
        }

        private void ProcessSceneEnvironment(DataRow row)
        {
            
        }

        private void ProcessSceneGeometry(DataRow row)
        {
        }

        private void ProcessSceneVegetationType(DataRow row)
        {
            Texture2D vegfile = ResourceManager.Instance.LoadContent<Texture2D>(row["filename"].ToString());
            Color[] data = LoadColorData(vegfile);
            ISceneScript loaderScript = ScriptManager.Instance.Get<ISceneScript>(row["script"].ToString(), "Scripts");

            for (int x = 0; x < vegfile.Width; x++)
            {
                for (int y = 0; y < vegfile.Height; y++)
                {
                    // Red = Vegetation Type
                    // Green = Mesh
                    // Blue = Scale

                    loaderScript.Execute(new object[] { data[x + y * vegfile.Width], this, SceneManager.Instance.Terrain.Scale.X * x, SceneManager.Instance.Terrain.Scale.Y * y });
                }
            }
        }

        /// <summary>
        /// returns the Color in an array of colors
        /// </summary>
        /// <param name="textureFile"></param>
        /// <returns></returns>
        private Color[] LoadColorData(Texture2D textureFile)
        {
            Color[] heightMapColors = new Color[textureFile.Width * textureFile.Height];
            textureFile.GetData(heightMapColors);
            return heightMapColors;
        }

        #endregion
    }
}
